import json
import logging
import os
import re
import time
import uuid

import jieba
import requests
from django.conf import settings
from django.shortcuts import render
from langchain.agents import ZeroShotAgent, AgentExecutor, StructuredChatAgent
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from openai import OpenAI
from rest_framework.response import Response
from rest_framework.views import APIView
import redis

from chat.chat_agent import labor_law_tool, education_tool, resume_tool, generate_resume_tool
from rag_test.ai_labor_law_response import get_labor_law_response
from rag_test.ai_resume_generator import resume_generator

# 初始化Redis连接
redis_client = redis.Redis(
    host=settings.REDIS_HOST,
    port=settings.REDIS_PORT,
    db=settings.REDIS_DB,
    decode_responses=True
)


def preprocess_text(user_input):
    """
    对用户输入进行预处理
    """
    # 1.去除用户输入中的特殊符号
    clean_text = re.sub(r"[*&^%$#@!~`]", "", user_input)
    # 2.把中文的符号转换成英文符号
    clean_text.replace("，", ",").replace("。", ".").replace("？", "?").replace("！", "!").replace("：", ":")
    # 3.去除多余的空格
    return clean_text.strip()


def jieba_cut(clean_text):
    """
    对用户输入进行分词
    """
    import os
    from django.conf import settings

    # 1.加载自定义词典,让模型识别到自定义词典中的词汇
    # 构建词典文件的绝对路径
    dict_path = os.path.join(os.path.dirname(__file__), "boss_zhipin_dict.txt")
    if os.path.exists(dict_path):
        jieba.load_userdict(dict_path)
    else:
        print(f"警告: 词典文件不存在: {dict_path}")
    words = jieba.cut(clean_text, cut_all=False
                      )
    stop_words = {"的", "了", "呢", "吗", "吧", "啊", "呢", "呢了"}
    filter_words = []
    for word in words:
        # 如果词汇不在停用词列表中，则放在filter_words列表中
        if word not in stop_words:
            print(word)
            filter_words.append(word)

    return filter_words


# 敏感词库
sensitive_words = {
    "ad": {"加微信", "微信号", "加QQ", "QQ号", "加V", "V号", "加微信"},
    "illegal": {"偷税", "非法", "漏税"},
    "irrelevant": {"娱乐", "八卦", "股票"},
    "abuse": {"垃*******圾", "蠢货"},
    "yellow": {"色*******情", "黄赌毒"},
    "politics": {"政******治", "敏感"},
    "sex": {"*", "*爱"},
    "terrorism": {"恐****怖", "暴*******恐"}
}

pattern_sensitive = {
    "phone": re.compile(r"1[3-9]\d{9}"),
    "qq": re.compile(r"[1-9]\d{4,10}"),
    "wechat": re.compile(r"wxid_\w+"),
}


def check_sensitive(core_words):
    """
    检查用户输入是否包含敏感词汇
    """
    for word in core_words:
        if word in sensitive_words:
            for key, value in sensitive_words.items():
                if word in value:
                    return True

    for word in core_words:
        for key, value in pattern_sensitive.items():
            if re.search(value, word):
                return True


def is_identity_verify_intent(filter_words):
    print("检查用户输入是否有验证学历的意图...", filter_words)

    resume_keywords = ["帮我生成一份简历", "帮我生成简历"]

    education_keywords = ["验证学历", "查学历", "学历真假", "学历验证",
                          "学信网", "验证码", "学历证明", "毕业证",
                          "教育背景", "学历查询", "验证一下学历"]
    result = {
        "success": True,
        "flag": "ordinary"
    }

    # 判断是否包含关键词
    for keyword in education_keywords:
        if keyword in filter_words:
            print("用户输入的文字有验证学历的意图...", keyword)
            result = {
                "success": True,
                "flag": "education"
            }
            return result

    # 验证是否包含验证码
    vcode_pattern = r'[A-Z0-9]{8,20}'
    for word in filter_words:
        print("检查用户输入是否包含验证码...", word)
        if re.search(vcode_pattern, word):
            print("用户输入的文字有验证码...", word)
            result = {
                "success": True,
                "flag": "education"
            }
            return result

    labor_law_keywords = [
        "劳动合同", "劳动法", "工资", "薪酬", "加班", "加班费",
        "辞职", "离职", "解雇", "辞退", "经济补偿", "赔偿金",
        "试用期", "社保", "五险一金", "工伤", "工龄", "无固定期限",
        "未签合同", "双倍工资", "解除合同", "劳动仲裁", "劳动纠纷"
    ]

    sum = 0

    for law_keyword in labor_law_keywords:
        for user_word in filter_words:
            if law_keyword in user_word:
                sum += 1
    if sum > 1:
        print("用户输入的文字有劳动合同咨询的意图...", "法律")
        result = {
            "success": True,
            "flag": "labor_law"
        }
        return result

    for resume in resume_keywords:
        for user_word in filter_words:
            if resume in user_word:
                print("用户输入的文字有生成简历的意图...", resume)
                result = {
                    "success": True,
                    "flag": "resume"
                }
                return result
    return result


def extract_verification_code(question):
    print("检查用户输入是否包含验证码...", question)
    vcode_pattern = r'[a-zA-Z0-9]{8,20}'
    matchs = re.findall(vcode_pattern, question)
    if matchs:
        print("用户输入的文字有验证码...", matchs[0])
        return matchs[0]
    return None


def verify_education(vcode):
    education_info = redis_client.hget("boss:chat:verify_education:vcode", vcode)
    print("检查用户输入的验证码是否在缓存中...", vcode, education_info)
    if education_info:
        print("用户输入的验证码在缓存中...", education_info)
        return {
            "success": True,
            "data": json.loads(education_info),
            "message": "成功"
        }

    api_url = f"https://www.apimy.cn/api/xxw/bgcx?key={os.getenv("MY_XXW_BGCX_API_KEY")}"
    response = requests.post(api_url, data={'vcode': vcode.upper()})
    # 获取响应内容
    result = response.json()

    # 打印结果
    print(result)
    print(type(result))
    if result["code"] == 200:
        redis_client.hset("boss:chat:verify_education:vcode", vcode, json.dumps(result["data"]))
        return {
            "success": True,
            "data": result["data"],
            "message": "成功"
        }

    else:
        return {
            "success": False,
            "data": result["msg"],
            "message": "验证失败"
        }


def format_education_result(education_result):
    if not education_result.get("success"):
        # 验证失败
        return f"""❌ 学历验证失败

        失败原因：{education_result.get('data', '未知错误')}

        建议：
        • 请检查验证码是否输入正确
        • 确认验证码是否已过期
        • 如有疑问，可要求候选人重新提供验证码"""

        # 验证成功的情况
    data = education_result.get('data', {})

    return f"""✅ 学历验证成功！

    👤 **基本信息**
    姓名：{data.get('姓名', 'N/A')}
    性别：{data.get('性别', 'N/A')}
    出生日期：{data.get('出生日期', 'N/A')}

    🎓 **学历信息**
    学校：{data.get('学校名称', 'N/A')}
    专业：{data.get('专业', 'N/A')}
    学历层次：{data.get('层次', 'N/A')}
    学制：{data.get('学制', 'N/A')}
    毕业时间：{data.get('毕（结）业日期', 'N/A')}

    📋 **验证详情**
    证书编号：{data.get('证书编号', 'N/A')}
    学历类别：{data.get('学历类别', 'N/A')}
    学习形式：{data.get('学习形式', 'N/A')}
    毕业状态：{data.get('毕（结）业', 'N/A')}

    该学历信息真实有效，可以放心录用。"""


def get_normal_ai_response(session_id, question):
    print("tools====")
    # 4. 调用AI大模型生成回复
    ai_message = []
    message_list_key = f"boss:chat:messagelist:{session_id}"

    def get_response(messages):
        client = OpenAI(
            api_key="sk-6434b554122c4b049ceb805d703f695b",
            base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        )

        completion = client.chat.completions.create(
            model="qwen-plus",
            messages=messages,
            tools=[{
                "type": "function",
                "function": {
                    "name": "verify_education",
                    "description": "验证学历证书",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "vcode": {
                                "type": "string",
                                "description": "学历验证码"
                            }
                        },
                        "required": ["vcode"]
                    }
                }
            }]
        )

        # 添加调试信息
        print(f"模型完整响应: {completion}")

        # 检查是否有工具调用
        choice = completion.choices[0]
        if hasattr(choice.message, 'tool_calls') and choice.message.tool_calls:
            tool_call = choice.message.tool_calls[0]
            if tool_call.function.name == "verify_education":
                import json
                try:
                    args = json.loads(tool_call.function.arguments)
                    print(f"调用的参数: {args}")
                    result = verify_education(args["vcode"])
                    print(f"工具调用结果: {result}")
                    return format_education_result(result)
                except Exception as e:
                    print(f"工具调用出错: {e}")
                    return "处理学历验证时出现错误，请稍后重试。"

        # 返回正常内容
        content = completion.choices[0].message.content
        print(f"模型返回内容: {content}")
        return content if content else "抱歉，我没有理解您的问题，请您重新描述一下。"
        # 5. 从Redis中获取最新的10条消息作为对话历史

    messages = redis_client.lrange(message_list_key, 0, 9)

    print(f"从redis取的最新10个messages:{messages}")
    for message in reversed(messages):
        message = json.loads(message)
        ai_message.append(
            {'role': message['role'], 'content': message['content']}
        )
    prompt_text = """
       ##角色定位
       你是Boss直聘平台的专业智能招聘顾问，精通企业招聘流程、求职者求职技巧、平台功能规则及人力资源基础常识，需以“解决用户实际招聘/求职问题”为核心，提供实用、准确、易懂的回答。
       现在你还具备了学历验证的功能,可以帮助用户验证学历信息。如果用户提到验证学历相关需求，请引导用户提供学信网验证码。
       ##核心任务
       1. 接收用户在Boss直聘平台的提问（用户身份可能是企业HR或求职者），先判断用户身份及问题场景，再针对性解答；
       2. 若用户问题涉及平台功能（如“如何发布职位”“怎么查看简历联系方式”），需按平台最新规则（以企业/求职者端实际操作路径为准）分步说明；
       3. 若用户问题涉及招聘技巧（如“HR如何筛选销售简历”“求职者怎么写简历亮点”），需提供可落地的方法，避免空泛建议；
        ### 场景规则
       - 拒绝回答与Boss直聘招聘场景和人力资源场景和求职场景无关的问题（如生活常识、娱乐八卦等），若用户提问偏离，需礼貌引导：“抱歉，目前仅能解答Boss直聘平台相关的招聘/求职问题，你可以说说具体的招聘需求或求职疑问哦～”；
       - 回答需简洁聚焦，避免冗余：HR类问题侧重“效率/合规”，求职者类问题侧重“实用/落地”；
       - 若用户问题模糊（如“怎么找工作”），需先追问关键信息：“为了更精准帮你，想了解你目前的求职方向（如行业/岗位），或是否在Boss直聘遇到了具体操作问题呀？”
       
       ### 输出要求
       1. 语言风格：口语化但专业，避免生硬术语（如解释“五险一金”时，可补充“即养老保险、医疗保险、失业保险、工伤保险、生育保险及住房公积金”）；
       2. 结构清晰：复杂问题（如操作类）用“步骤”呈现，多维度问题（如简历优化）用“要点”拆分；
       3. 优先级：先给结论/核心方法，再补充细节，确保用户快速获取关键信息。
       """

    system_message = {"role": "system", "content": prompt_text}
    ai_message.insert(0, system_message)
    print(f"传给大模型的messages:{ai_message}")
    # 直接返回get_response的结果，因为它可能返回字符串或completion对象
    assistant_output = get_response(ai_message)

    # 如果返回的是completion对象，则提取content
    if hasattr(assistant_output, 'choices'):
        assistant_output = assistant_output.choices[0].message.content

    print(f"大模型输出:{assistant_output}")
    return assistant_output


def get_normal_ai_response_old(session_id, question):
    # 4. 调用AI大模型生成回复
    ai_message = []
    message_list_key = f"boss:chat:messagelist:{session_id}"

    def get_response(messages):
        """
        调用AI大模型API获取回复

        Args:
            messages: 包含对话历史的消息列表

        Returns:
            completion: AI模型的回复结果
        """
        client = OpenAI(
            # 若没有配置环境变量，请用阿里云百炼API Key将下行替换为：api_key="sk-xxx",
            api_key="sk-",
            # base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
            base_url="http://localhost:11434/v1",

        )
        # 模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
        completion = client.chat.completions.create(
            model="qwen:latest",
            # model="qwen-plus",
            messages=messages,
        )
        return completion

    # 5. 从Redis中获取最新的10条消息作为对话历史
    messages = redis_client.lrange(message_list_key, 0, 9)

    print(f"从redis取的最新10个messages:{messages}")
    for message in reversed(messages):
        message = json.loads(message)
        ai_message.append(
            {'role': message['role'], 'content': message['content']}
        )
    prompt_text = """
      ##角色定位
      你是Boss直聘平台的专业智能招聘顾问，精通企业招聘流程、求职者求职技巧、平台功能规则及人力资源基础常识，需以“解决用户实际招聘/求职问题”为核心，提供实用、准确、易懂的回答。
      现在你还具备了学历验证的功能,可以帮助用户验证学历信息。如果用户提到验证学历相关需求，请引导用户提供学信网验证码。
      ##核心任务
      1. 接收用户在Boss直聘平台的提问（用户身份可能是企业HR或求职者），先判断用户身份及问题场景，再针对性解答；
      2. 若用户问题涉及平台功能（如“如何发布职位”“怎么查看简历联系方式”），需按平台最新规则（以企业/求职者端实际操作路径为准）分步说明；
      3. 若用户问题涉及招聘技巧（如“HR如何筛选销售简历”“求职者怎么写简历亮点”），需提供可落地的方法，避免空泛建议；
       ### 场景规则
      - 拒绝回答与Boss直聘招聘场景和人力资源场景和求职场景无关的问题（如生活常识、娱乐八卦等），若用户提问偏离，需礼貌引导：“抱歉，目前仅能解答Boss直聘平台相关的招聘/求职问题，你可以说说具体的招聘需求或求职疑问哦～”；
      - 回答需简洁聚焦，避免冗余：HR类问题侧重“效率/合规”，求职者类问题侧重“实用/落地”；
      - 若用户问题模糊（如“怎么找工作”），需先追问关键信息：“为了更精准帮你，想了解你目前的求职方向（如行业/岗位），或是否在Boss直聘遇到了具体操作问题呀？”
      ### 输出要求
      1. 语言风格：口语化但专业，避免生硬术语（如解释“五险一金”时，可补充“即养老保险、医疗保险、失业保险、工伤保险、生育保险及住房公积金”）；
      2. 结构清晰：复杂问题（如操作类）用“步骤”呈现，多维度问题（如简历优化）用“要点”拆分；
      3. 优先级：先给结论/核心方法，再补充细节，确保用户快速获取关键信息。
      """

    system_message = {"role": "system", "content": prompt_text}
    ai_message.insert(0, system_message)
    print(f"传给大模型的messages:{ai_message}")
    assistant_output = get_response(ai_message).choices[0].message.content

    print(f"大模型输出:{assistant_output}")
    return assistant_output


# Create your views here.


class MutChatAPIView(APIView):

    def post(self, request):
        """
        多轮对话
        """
        # 1:接受前端传递的用户的问题
        messages = request.data.get('messages')
        if not messages:
            return Response({'code': 0, 'message': '请输入问题'})

        # 初始化一个 messages 数组
        # messages = [
        #     {
        #         "role": "system",
        #         "content": """
        #         你是一个地道的北京人，你负责给用户推荐北京小吃和做法
        #         """,
        #     }
        # ]

        def get_response(messages):
            client = OpenAI(
                # 若没有配置环境变量，请用阿里云百炼API Key将下行替换为：api_key="sk-xxx",
                api_key=os.getenv("DASHSCOPE_API_KEY"),
                # base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
                base_url="http://localhost:11434/v1",
            )
            # 模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
            completion = client.chat.completions.create(model="qwen:latest", messages=messages)
            return completion

        # 将用户问题信息添加到messages列表中
        # messages.append({"role": "user", "content": question})
        # print(f"用户问题：{question}")
        # print("\n")
        print(f"messages:{messages}")
        assistant_output = get_response(messages).choices[0].message.content
        # 将大模型的回复信息添加到messages列表中
        messages.append({"role": "assistant", "content": assistant_output})
        print(f"模型输出：{assistant_output}")
        print("\n")

        return Response({'code': 1, 'message': '成功', 'data': {
            "answer": assistant_output,
            "messages": messages
        }})


class CreateChatAPIView(APIView):
    """
    创建新会话接口业务逻辑
    """

    def post(self, request):
        # 1.处理请求数据，获取可选的会话标题
        user_id = request.data.get("user_id")
        title = request.data.get("title", "新会话")

        # 2:验证用户身份
        if not user_id:
            return Response({'code': 0, 'message': '请登录,再操作'})
        # 3. 生成唯一会话ID
        session_id = str(uuid.uuid4())
        print(f"新会话session_id:{session_id}")

        current_timestamp = int(time.time() * 1000)

        # 4. 存储会话基本信息到Hash结构 (项目名:业务名:功能名:{})
        session_key = f"boss:chat:session:{session_id}"
        redis_client.hset(
            session_key,
            mapping={
                'createTime': current_timestamp,
                'lastMessageTime': current_timestamp,
                'title': title,
                'status': 'active',
                'userId': user_id
            }
        )
        # Redis的expire命令默认时间单位是秒,设置过期时间:5天
        redis_client.expire(session_key, 60 * 60 * 24 * 5)

        # 5. 存储会话列表到列表结构 (项目名:业务名:功能名:{})
        session_list_key = f"boss:chat:sessionlist:{user_id}"
        redis_client.lpush(session_list_key, session_id)
        redis_client.expire(session_list_key, 60 * 60 * 24 * 5)
        return Response({'code': 1, 'message': '创建成功', 'data': {
            'sessionId': session_id
        }})


tools = [labor_law_tool, education_tool, resume_tool, generate_resume_tool]

llm = ChatOpenAI(
    model_name="qwen-plus",
    api_key="sk-efa04219920b4938b7573cf1b80f9784",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

prompt_template = """
你是一个专业的人力资源专家,你具有以下工具:
{tools}
对话历史:{boss_chat_history}  
使用规则:
1:先理解问题:无需工具则直接回答,需要工具则调用工具(根据工具的描述匹配)
2:调用工具必须用格式：```json{{"name":"工具名","parameters":{{"参数名":"参数值"}}}} ```（参数需齐全）；
3: 生成简历必须分二步执行：
   - 第一步：调用 `resume_tool` 获取基础信息（姓名、技能等）。
   - 第二步：将完整数据组装为严格的JSON格式，调用 `generate_resume_tool`,在调用generate_resume_tool 之前必须调用resume_tool
   
   重要提示：在调用generate_resume_tool时，传入的参数必须是严格的JSON格式字符串，不能是其他格式。
   
   示例格式：
   ```json
{{"基本信息": {{
"姓名": "test_user_1",
    "手机号": "13800000001",
    "性别": "女",
    "出生日期": "1990-02-22",
    "学历信息": "None",
    "邮箱": "test_user_1@example.com",
    "当前状态": "在职看机会",
    "个人评价": "我是张三，一名经验丰富的开发工程师，热爱技术创新。"
  }},
  "求职意向": {{
"岗位": "",
    "期望薪资": "",
    "城市": ""
  }},
  "工作经历": [
    {{
"公司名": "腾讯科技",
      "开始时间": "2024-06-06",
      "结束时间": "至今",
      "职位": "产品经理",
      "工作描述": "负责核心业务系统开发，参与需求分析和系统设计，编写高质量代码。",
      "所属行业": "IT互联网",
      "薪资范围": "26K-50K"
    }}
  ],
  "专业技能": {{
"MySQL": "了解",
    "Scala": "精通",
    "MPLS": "了解",
    "VPN": "基础",
    "OAuth": "基础",
    "数据挖掘": "熟练",
    "Kibana": "熟练",
    "Jenkins X": "基础",
    "LoadRunner": "了解",
    "Rust": "基础"
  }},
  "项目经历": [
    {{
"项目名称": "数据可视化分析平台",
      "项目描述": "基于Kibana与Elasticsearch构建企业级数据分析平台，实现日志数据的实时监控与可视化展示。",
      "项目角色": "核心开发",
      "项目时间": "2023-08 至 2024-05",
      "项目技术栈": "Kibana, Elasticsearch, Scala, Jenkins X",
      "个人职责": "负责数据处理模块的开发与优化，设计日志数据采集架构，提升系统性能约30%。"
    }},
    {{
"项目名称": "用户行为分析系统",
      "项目描述": "构建基于Hadoop与Spark的数据分析系统，用于分析用户行为路径与转化率。",
      "项目角色": "数据工程师",
      "项目时间": "2022-05 至 2023-07",
      "项目技术栈": "Scala, Spark, Hadoop, MySQL",
      "个人职责": "主导数据处理流程设计，实现ETL流程自动化，提升数据处理效率。"
    }},
    {{
"项目名称": "微服务持续集成平台搭建",
      "项目描述": "使用Jenkins X搭建微服务项目的持续集成与部署流水线，提升交付效率。",
      "项目角色": "DevOps工程师",
      "项目时间": "2021-10 至 2022-04",
      "项目技术栈": "Jenkins X, Kubernetes, Docker",
      "个人职责": "负责CI/CD流程设计与实施，实现自动化测试与部署，缩短发布周期。"
    }},
    {{
"项目名称": "高并发数据挖掘平台",
      "项目描述": "基于Rust与Scala构建高性能数据挖掘平台，用于处理大规模用户数据。",
      "项目角色": "后端开发工程师",
      "项目时间": "2020-03 至 2021-09",
      "项目技术栈": "Rust, Scala, MySQL, LoadRunner",
      "个人职责": "负责核心算法模块开发与性能优化，使用LoadRunner进行压力测试，提升系统稳定性。"
    }},
    {{
"项目名称": "企业级身份认证系统",
      "项目描述": "基于OAuth协议构建统一身份认证系统，支持多业务系统接入与权限管理。",
      "项目角色": "系统架构师",
      "项目时间": "2019-06 至 2020-02",
      "项目技术栈": "OAuth, Scala, MySQL",
      "个人职责": "设计系统架构与认证流程，保障系统安全性与扩展性，成功接入10+内部系统。"
    }}
  ]
}}
```

用户的问题:{{input}}

最终回答要求：
请严格按照以下格式进行最终回答：
最终回答: <你的最终回答内容>
"""
prompt = PromptTemplate(
    template=prompt_template,
    input_variables=["tools", "input","boss_chat_history"],
)

# 核心:创建会话记忆,
memory = ConversationBufferMemory(
    memory_key="boss_chat_history",
    return_messages=True,  # 返回Message对象，方便Agent理解
)

# 构建Agent
agent = StructuredChatAgent.from_llm_and_tools(
    llm=llm,
    tools=tools,
    prompt=prompt,
    verbose=True,
)

# 构建执行器
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=5,
    memory = memory,  # 关键:把记忆绑定到执行器

)


class ChatAPIView(APIView):
    def post(self, request):
        question = request.data.get("question")
        print("历史记录:",memory.buffer)
        res = agent_executor.invoke({
            "input": f"{question}"}, return_only_outputs=False)

        return Response({
            "问题": res["input"],
            "回答": res["output"]
        })


class SendMessageAPIView(APIView):
    """
    发送消息接口业务逻辑
    
    处理用户发送的消息，将其存储到Redis中，调用AI大模型生成回复，
    并将AI回复也存储到Redis中。
    """

    def process_one(self, session_id, question, user_id):
        # ====原有的逻辑保持不变======

        # 2. 验证必要参数
        if not all([session_id, question, user_id]):
            return Response({'code': 0, 'message': '参数不全'})

        # 预处理: 清洗数据
        clean_text = preprocess_text(question)
        if not clean_text:
            return Response({'code': 0, 'message': '请输入有效的问题'})
        # 分词
        filter_words = jieba_cut(clean_text)

        # 判断是否包含敏感词
        check_sensitive(filter_words)
        return filter_words

    def process_two(self, question, session_id):
        # 3. 把用户消息存入到Redis
        meesage_id = str(uuid.uuid4())
        create_time = int(time.time() * 1000)

        user_message = {
            "meesage_id": meesage_id,
            "role": "user",
            "content": question,
            "create_time": create_time
        }
        message_list_key = f"boss:chat:messagelist:{session_id}"
        redis_client.lpush(message_list_key, json.dumps(user_message))
        return meesage_id, message_list_key

    def post(self, request):
        """
        处理POST请求，接收并处理用户发送的消息
        
        Args:
            request: HTTP请求对象，包含session_id, question, user_id参数
            
        Returns:
            Response: 包含处理结果的HTTP响应对象
                - code: 状态码，1表示成功，0表示失败
                - message: 状态信息
                - data: 返回的数据，包括messageId, sessionId, question, answer
        """
        # 1. 获取请求参数
        session_id = request.data.get("session_id")
        question = request.data.get("question")
        user_id = request.data.get("user_id")
        print("session_id:", session_id)
        print("question:", question)
        print("user_id:", user_id)

        filter_words = self.process_one(session_id, question, user_id)
        meesage_id, message_list_key = self.process_two(question, session_id)
        # 判断意图的方法
        is_identity_verify = is_identity_verify_intent(filter_words)
        if is_identity_verify.get("flag") == "education":
            print("是学历验证请求")
            # 2. 提取验证码
            vcode = extract_verification_code(question)
            print("提取后的验证码：", vcode)
            if vcode:
                identity_verify_result = verify_education(vcode)  # 3. 调用学历验证API
                # 4. 格式化结果
                assistant_output = format_education_result(identity_verify_result)
                # print("====get_normal_ai_response====")
                # assistant_output = get_normal_ai_response(session_id, question)
                # assistant_output = get_normal_ai_response_old(session_id,question)
            else:
                assistant_output = "我看到您想要验证学历，但没有找到验证码。请提供学信网验证码，格式通常是8-20位大写字母和数字组合，如：BS4X8VKM3BN9FC1C"
        elif is_identity_verify.get("flag") == "labor_law":
            assistant_output = get_labor_law_response(question)
            print("咨询劳动法问题的答案:", assistant_output)
        elif is_identity_verify.get("flag") == "resume":
            # str = "帮我生成一份简历，我的期望薪资是10000，期望工作城市是北京，期望岗位是python工程师"
            # user_id, desired_position, desired_city, desired_money
            # 正则表达式,提取期望职位、期望城市、期望薪资
            # 使用正则表达式提取期望信息
            desired_position_match = re.search(r'期望岗位[是:：]\s*([^，,\n。.]+)', question)
            desired_city_match = re.search(r'期望(工作)?城市[是:：]\s*([^，,\n。.]+)', question)
            desired_money_match = re.search(r'期望薪资[是:：]\s*(\d+)', question)

            desired_position = desired_position_match.group(1).strip() if desired_position_match else ""
            desired_city = desired_city_match.group(2).strip() if desired_city_match else ""
            desired_money = desired_money_match.group(1).strip() if desired_money_match else ""

            assistant_output = resume_generator(user_id, desired_position, desired_city, desired_money)
        else:
            assistant_output = get_normal_ai_response_old(session_id, question)
            # 不是验证要学历,则调用大模型

        # 6. 将AI回复存入Redis
        ai_message_id = str(uuid.uuid4())
        ai_create_time = int(time.time() * 1000)

        ai_re_message = {
            "meesage_id": ai_message_id,
            "role": "assistant",
            "content": assistant_output,
            "create_time": ai_create_time
        }

        redis_client.lpush(message_list_key, json.dumps(ai_re_message))

        # 7. 更新会话的最后消息时间
        session_key = f"boss:chat:session:{session_id}"
        redis_client.hset(session_key, "lastMessageTime", ai_create_time)

        messages = redis_client.lrange(message_list_key, 0, -1)
        messages = [json.loads(message) for message in messages]

        return Response({'code': 1, 'message': '发送成功', 'data': {
            "messageId": meesage_id,
            "sessionId": session_id,
            "question": question,
            "answer": assistant_output,
            "messageList": messages
        }})


class GetChatSessionListAPIView(APIView):
    """
    获取会话列表接口业务逻辑

    处理用户请求，返回该用户下的所有会话列表。
    """

    def get(self, request):
        user_id = request.query_params.get("user_id")
        if not user_id:
            return Response({'code': 0, 'message': '请登录,再操作'})

        session_list_key = f"boss:chat:sessionlist:{user_id}"
        session_list = redis_client.lrange(session_list_key, 0, -1)
        print(f"session_list:{session_list}")

        # 批量获取会话基本信息
        pipeline = redis_client.pipeline()
        for session_id in session_list:
            session_key = f"boss:chat:session:{session_id}"

            pipeline.hgetall(session_key)
            message_list_key = f"boss:chat:messagelist:{session_id}"
            # 获取最后一条消息
            pipeline.lindex(message_list_key, 0)

        results = pipeline.execute()
        print(f"results:{results}")
        print(type(results))

        session_list_info = []
        # 每两个结果为一组：第一个是会话信息（字典），第二个是最后一条消息（字符串或None）
        for i in range(0, len(results), 2):
            session_info = results[i]
            last_message_str = results[i + 1]

            # 处理最后一条消息
            last_message_content = ""
            if last_message_str:
                try:
                    last_message = json.loads(last_message_str)
                    last_message_content = last_message.get("content", "")
                except json.JSONDecodeError:
                    # 如果解析失败，使用原始字符串
                    last_message_content = str(last_message_str)
                # last_message_content只要前10个字符,后面...  表示
                last_message_content = last_message_content[:10] + "..." if len(
                    last_message_content) > 10 else last_message_content

            # 构建会话信息
            session_list_info.append({
                "sessionId": session_list[i // 2] if i // 2 < len(session_list) else "",
                "title": session_info.get("title", ""),
                "lastMessageTime": session_info.get("lastMessageTime", ""),
                "lastMessage": last_message_content,
                "status": session_info.get("status", ""),
                "userId": user_id
            })

        return Response({'code': 1, 'message': '获取成功', 'data': session_list_info})


class GetChatMessageAPIView(APIView):
    """
    获取会话消息列表接口业务逻辑

    处理用户请求，返回该会话下的所有消息列表。
    """

    def post(self, request):
        session_id = request.data.get("session_id")
        if not session_id:
            return Response({'code': 0, 'message': '请选择会话'})
        message_list_key = f"boss:chat:messagelist:{session_id}"
        messages = redis_client.lrange(message_list_key, 0, -1)
        messages = [json.loads(message) for message in messages]
        return Response({'code': 1, 'message': '获取成功', 'data': messages})
